#include <cpurg.h>
#include <iostream>
#include <purg.h>
#include <cassert>

void  test_vals ( int *gen1 , purg::parallel_gen &gen2 , size_t amt )
{
  for ( size_t i = 0 ; i != amt ; i++ )
  {
    double  v1;
    float   v2;
    int     v3 , v4;
    long    v5 , v6;
    size_t  v7 , v8;
    unsigned int v9 , v10;
    unsigned long v11 , v12;

    gen2.get ( v1 , 0. , 1. );
    gen2.get ( v2 , 0. , 1. );
    gen2.get ( v3 , 10 , 1000 );
    gen2.get ( v4 );
    gen2.get ( v5 , 10l , 1000l );
    gen2.get ( v6 );
    gen2.get ( v7 , 10ul , 1000ul );
    gen2.get ( v8 );
    gen2.get ( v9 , 10u , 1000u );
    gen2.get ( v10 );
    gen2.get ( v11 , 10ul , 1000ul );
    gen2.get ( v12 );
    
    assert ( v1 == purg_double ( gen1 , 0. , 1. ) );
    assert ( v2 == purg_float ( gen1 , 0. , 1. ) );
    assert ( v3 == purg_int_bounded ( gen1 , 10 , 1000 ) );
    assert ( v4 == purg_int ( gen1 ) );
    assert ( v5 == purg_long_bounded ( gen1 , 10 , 1000 ) );
    assert ( v6 == purg_long ( gen1 ) );
    assert ( v7 == purg_size_t_bounded ( gen1 , 10 , 1000 ) );
    assert ( v8 == purg_size_t ( gen1 ) );
    assert ( v9 == purg_uint_bounded ( gen1 , 10 , 1000 ) );
    assert ( v10 == purg_uint ( gen1 ) );
    assert ( v11 == purg_ulong_bounded ( gen1 , 10 , 1000 ) );
    assert ( v12 == purg_ulong ( gen1 ) );
  }
}

int main ( int argc , char ** argv )
{
  purg::parallel_gen generator ( 0 , 0 , 0 );
  purg::random_variable<size_t , purg::parallel_gen> rint ( 10 , 1000000 , generator );
  for ( size_t i = 0 ; i != 1000 ; i++ )
  {
    size_t seed1 = rint;
    size_t seed2 = rint;
    size_t stream_id = rint;
    int *gen1 = purg_init_rng ( seed1 , seed2 , stream_id );

    purg::parallel_gen gen2 ( seed1 , seed2 , stream_id );
    test_vals ( gen1 , gen2 , 1000 );
    purg_destroy_rng ( gen1 );
  }
  std::cout << "C interface passes" << std::endl;
}
